﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Windows.Forms;
using DevExpress.Data;
using DevExpress.Utils;
using DevExpress.XtraBars;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.EditForm.Helpers.Controls;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraPrinting;
using NAGFwk.BL;
using NAGFwk.UI.Properties;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using System.Drawing;
using DevExpress.XtraBars.Docking2010.Views.WindowsUI;

namespace NAGFwk.UI
{
    public partial class BaseContentDetail : BaseModule
    {
       

        private bool _show = false;
        private bool _HasModelErrors = false;
        protected override bool AutoMergeRibbon { get { return true; } }
        public override IPrintable PrintableComponent { get { return gcBaseContentDetail; } }
        public override IPrintable ExportComponent { get { return gcBaseContentDetail; } }
        public event BaseContentDetailRowUpdated OnUpdateGrid;
        public event BaseContentDetailCancelEditform OnCancel;
        public RowObjectEventArgs E = null;
        public delegate void BaseContentDetailRowUpdated(object m, RowObjectEventArgs e);
        public delegate void BaseContentDetailCancelEditform();

        /// <summary>
        /// Enable or Disable the custom columns process.
        /// If true, then the columns will show like the designer
        /// </summary>
        protected virtual bool IgnoreCustomColumns { get { return false; } }

        protected void MapItLoad<TEntity>(IBaseController<TEntity> childController)
            where TEntity : class
        {
            try
            {
                MapItRefresh(childController);
            }
            catch (Exception ex)
            {
                new ErrorForm(ex).ShowDialog(this);
                MapItRefresh(childController);
                _HasModelErrors = true;
            }
        }

        protected void MapItDelete<TEntity>(IBaseController<TEntity> childController)
            where TEntity : class
        {
            try
            {
                DeleteItem(childController);
            }
            catch (Exception ex)
            {
                new ErrorForm(ex).ShowDialog(this);
                MapItRefresh(childController);
                _HasModelErrors = true;
            }
        }

        protected void MapItUpdate<TEntity>(RowObjectEventArgs e, IBaseController<TEntity> childController)
            where TEntity : class
        {
            try
            {
                InsertOrUpdateItem(e, childController);
            }
            catch (Exception ex)
            {
                new ErrorForm(ex).ShowDialog(this);
                MapItRefresh(childController);
                _HasModelErrors = true;
            }
        }

        protected IBaseController<TEntity> MapItRefresh<TEntity>(IBaseController<TEntity> childController)
            where TEntity : class
        {
            try
            {
                bsBaseContentDetail.DataSource = childController.GetAll();
                gcBaseContentDetail.RefreshDataSource();
            }
            catch (Exception ex)
            {
                new ErrorForm(ex).ShowDialog(this);
                _HasModelErrors = true;
            }

            return childController;
        }

        protected virtual void ValidateRows(ValidateRowEventArgs e)
        {
        }

        public BaseContentDetail()
            : base()
        {
            InitializeComponent();
            SetInitialValues();
        }

        #region "Action Buttons"

        private void bbiOpen_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout != null)
                ((BaseCustomEditForm)gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout).IsOpen = true;

            gvBaseContentDetail.ShowEditForm();
        }

        private void bbiNew_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout != null)
            {
                gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout = (BaseCustomEditForm)Activator.CreateInstance(gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout.GetType());
                ((BaseCustomEditForm)gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout).IsNew = true;
            }
            gvBaseContentDetail.AddNewRow();
            gvBaseContentDetail.ShowEditForm();
        }

        private void bbiEdit_ItemClick(object sender, ItemClickEventArgs e)
        {
            OnEditOnGrid();
        }

        private void gvBaseContentDetail_DoubleClick(object sender, EventArgs e)
        {
            GridView view = (GridView)sender;

            Point pt = view.GridControl.PointToClient(Control.MousePosition);

            GridHitInfo info = view.CalcHitInfo(pt);

            if (info.InRow || info.InRowCell)
                if (gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout != null)
                    ((BaseCustomEditForm)gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout).IsEdit = true;
        }

        private void OnEditOnGrid()
        {
            if (gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout != null)
                ((BaseCustomEditForm)gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout).IsEdit = true;

            gvBaseContentDetail.ShowEditForm();
        }

        private void bbiShowAutoFilterRow_ItemClick(object sender, ItemClickEventArgs e)
        {
            gvBaseContentDetail.OptionsView.ShowAutoFilterRow = !gvBaseContentDetail.OptionsView.ShowAutoFilterRow;
        }

        private void bbiAutoFilterRowItemColumnMenu_ItemClick(object sender, ItemClickEventArgs e)
        {
            gvBaseContentDetail.OptionsMenu.ShowAutoFilterRowItem = !gvBaseContentDetail.OptionsMenu.ShowAutoFilterRowItem;
        }

        private void bbiShowColumnSelector_ItemClick(object sender, ItemClickEventArgs e)
        {
            ShowColumnSelector();
        }

        private void bbiShowSearchPanel_ItemClick(object sender, ItemClickEventArgs e)
        {
            gvBaseContentDetail.OptionsFind.AlwaysVisible = !gvBaseContentDetail.OptionsFind.AlwaysVisible;
        }

        #endregion

        private void SetInitialValues()
        {
            gvBaseContentDetail.OptionsBehavior.EditingMode = GridEditingMode.EditForm;
            gvBaseContentDetail.OptionsEditForm.ActionOnModifiedRowChange = EditFormModifiedAction.Default;
            gvBaseContentDetail.OptionsEditForm.ShowUpdateCancelPanel = DefaultBoolean.True;
            gvBaseContentDetail.RowUpdated += gvBaseContentDetail_RowUpdated;
        }

        private void ShowColumnSelector(bool showForm = true)
        {
            _show = !_show;
            if (_show)
            {
                if (showForm) gvBaseContentDetail.ColumnsCustomization();
            }
            else
                if (showForm) gvBaseContentDetail.DestroyCustomization();
        }

        private void DeleteItem<TEntity>(IBaseController<TEntity> childController) where TEntity : class
        {
            var Current = gvBaseContentDetail.GetFocusedRow();
            if (Current != null)
                if (MessageBox.Show(Resources.DeleteWarningMessage, Resources.DeleteWarningMessageTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    childController.DeleteLogical(((TEntity)Current));
                    MapItRefresh(childController);
                }
        }

        private void InsertOrUpdateItem<TEntity>(RowObjectEventArgs e, IBaseController<TEntity> childController) where TEntity : class
        {
            var Current = bsBaseContentDetail.Current;
            if (Current != null)
            {
                if (e.RowHandle < 0)
                    childController.Insert(((TEntity)Current));
                else
                    childController.Update(((TEntity)Current));
            }
        }

        private void BaseContentDetail_Load(object sender, EventArgs e)
        {
            //int i = 1;
            if (IgnoreCustomColumns)
            {
                //this.bbiGroupBy.LinksPersistInfo.Clear();

                //foreach (var _Column in gvBaseContentDetail.Columns.Where(x => x.Visible == true).ToList())
                //{
                //    var MyNewItemCol = new BarCheckItem();
                //    MyNewItemCol.Name = "Grouped" + _Column.Name;
                //    MyNewItemCol.Tag = _Column;
                //    MyNewItemCol.Caption = _Column.Caption;
                //    MyNewItemCol.GroupIndex = i;
                //    MyNewItemCol.Id = i;
                //    MyNewItemCol.CheckedChanged += MyNewItemCol_CheckedChanged;
                //    this.rcBaseContentDetail.Items.Add(MyNewItemCol);
                //    this.bbiGroupBy.LinksPersistInfo.Add(new LinkPersistInfo(MyNewItemCol));
                //    i++;
                //}
                return;
            }

            //this.bbiGroupBy.LinksPersistInfo.Clear();
            foreach (var column in gvBaseContentDetail.Columns.ToList())
            {
                string cachedName = ((GridColumn)(column)).GetCaption();
                if (column.ColumnEdit == null)
                {
                    if (cachedName.Trim().ToUpper().Contains("ID") || cachedName.ToUpper() == "ENABLE" || cachedName.ToUpper() == "DISPONIBLE")
                        SetColumnOptions(column);
                }
                else
                    column.Caption = cachedName.Trim().Replace("ID", "");

                //var MyNewItemCol = new BarCheckItem();
                //MyNewItemCol.Name = "Grouped" + column.Name;
                //MyNewItemCol.Tag = column;
                //MyNewItemCol.Caption = column.Caption;
                //MyNewItemCol.GroupIndex = i;
                //MyNewItemCol.Id = i;                
                //MyNewItemCol.CheckedChanged += MyNewItemCol_CheckedChanged;
                //this.rcBaseContentDetail.Items.Add(MyNewItemCol);
                //this.bbiGroupBy.LinksPersistInfo.Add(new LinkPersistInfo(MyNewItemCol));
                //i++;
            }
            expressionConditionsEditor1.Init(gvBaseContentDetail);
        }

        void MyNewItemCol_CheckedChanged(object sender, ItemClickEventArgs e)
        {

            gvBaseContentDetail.BeginSort();
            try
            {
                gvBaseContentDetail.ClearGrouping();
                var singleOrDefault = gvBaseContentDetail.Columns.SingleOrDefault(x => x.Name == ((GridColumn)e.Item.Tag).Name);
                if (singleOrDefault != null)
                    singleOrDefault.GroupIndex = 0;
            }
            finally
            {
                gvBaseContentDetail.EndSort();
            }
        }

        private static void SetColumnOptions(GridColumn column)
        {
            column.Visible = false;
            column.OptionsColumn.ShowInCustomizationForm = false;
            column.OptionsColumn.ShowInExpressionEditor = false;
        }

        private void gvBaseContentDetail_InvalidRowException(object sender, InvalidRowExceptionEventArgs e)
        {
            _HasModelErrors = true;
            e.ExceptionMode = ExceptionMode.DisplayError;
        }

        private void gvBaseContentDetail_ValidateRow(object sender, ValidateRowEventArgs e)
        {
            ValidateRows(e);
            _HasModelErrors = false;
        }

        private void bbiShowFilter_ItemClick(object sender, ItemClickEventArgs e)
        {
            gvBaseContentDetail.ShowFilterEditor(gvBaseContentDetail.FocusedColumn);
        }

        private void OnSortingCheckedChanged(object sender, ItemClickEventArgs e)
        {
            if (!((BarCheckItem)e.Item).Checked)
                return;

            gvBaseContentDetail.BeginSort();
            if (e.Item == bcAscending)
                foreach (var col in gvBaseContentDetail.Columns.AsParallel().ToList())
                    col.SortOrder = ColumnSortOrder.Ascending;
            if (e.Item == bcDescending)
                foreach (var col in gvBaseContentDetail.Columns.AsParallel().ToList())
                    col.SortOrder = ColumnSortOrder.Descending;
            if (e.Item == bcSortNone)
                foreach (var col in gvBaseContentDetail.Columns.AsParallel().ToList())
                    col.SortOrder = ColumnSortOrder.None;
            gvBaseContentDetail.EndSort();
        }

        private void gvBaseContentDetail_ShowingPopupEditForm(object sender, ShowingPopupEditFormEventArgs e)
        {
            if (gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout == null)
                return;

            foreach (Control control in e.EditForm.Controls)
            {
                if (!(control is EditFormContainer))
                    continue;

                foreach (Control nestedControl in control.Controls)
                {
                    if (!(nestedControl is PanelControl))
                        continue;

                    foreach (Control button in nestedControl.Controls)
                    {
                        if ((button is LabelControl))
                            continue;
                        if (button.Tag.ToString().ToUpper() == "OKBUTTON")
                        {
                            var simpleButton = button as SimpleButton;
                            simpleButton.Click -= editFormUpdateButton_Click;
                            simpleButton.Click += editFormUpdateButton_Click;
                        }
                        else if (button.Tag.ToString().ToUpper() == "CANCELBUTTON")
                        {
                            var simpleButton = button as SimpleButton;
                            simpleButton.Click -= editFormCancelButton_Click;
                            simpleButton.Click += editFormCancelButton_Click;
                        }
                    }
                }
            }
        }

        private void editFormCancelButton_Click(object sender, EventArgs e)
        {
            if (OnCancel != null)
                OnCancel();
        }
        private void editFormUpdateButton_Click(object sender, EventArgs e)
        {
            //if (_HasModelErrors)
            //    return;

            //if (gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout == null)
            //    return;

            //var myArgs = new FocusedRowObjectChangedEventArgs(gvBaseContentDetail.GetFocusedDataSourceRowIndex(), gvBaseContentDetail.GetDataRow(gvBaseContentDetail.GetFocusedDataSourceRowIndex()));
            //OnUpdateGrid(sender, myArgs);
        }

        void gvBaseContentDetail_RowUpdated(object sender, RowObjectEventArgs e)
        {
            if (_HasModelErrors)
                return;
            if (gvBaseContentDetail.OptionsEditForm.CustomEditFormLayout != null)
                OnUpdateGrid(sender, e);
        }

        private void barButtonItem1_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (expressionConditionsEditor1.Visible)
                expressionConditionsEditor1.Hide();
            else
                expressionConditionsEditor1.Show();
        }

        private void btnExpressionEditorForFocusedColum_ItemClick(object sender, ItemClickEventArgs e)
        {
            ConditionsEditor editor = new ConditionsEditor(gvBaseContentDetail.FocusedColumn, this.FindForm());
            this.FindForm().Refresh();
            editor.ShowDialog();
        }


    }
}
